Make menus only stay up if you release within 500 milliseconds.
authorSoeren Sandmann <sandmann@daimi.au.dk>
Tue, 1 Jun 2004 22:47:14 +0000 (22:47 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Tue, 1 Jun 2004 22:47:14 +0000 (22:47 +0000)
Wed Jun  2 00:39:58 2004  Soeren Sandmann  <sandmann@daimi.au.dk>

* gtk/gtkmenushell.c (gtk_menu_shell_button_release): Make menus
only stay up if you release within 500 milliseconds.
(gtk_menu_shell_button_press): Set the activate_time to the event
time when a button is pressed.

* gtk/gtkmenu.c (gtk_menu_motion_notify, gtk_menu_enter_notify):
Interprete button releases as activate when we have seen both an
enter an a motion event.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkmenu.c
gtk/gtkmenushell.c

index 93903f4e27aa8fb4012db3f729f48edff16b7090..bcce53faa95d6e420d35404069dc8a46d3eea205 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Jun  2 00:39:58 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_button_release): Make menus
+       only stay up if you release within 500 milliseconds.
+       (gtk_menu_shell_button_press): Set the activate_time to the event
+       time when a button is pressed.
+
+       * gtk/gtkmenu.c (gtk_menu_motion_notify, gtk_menu_enter_notify):
+       Interprete button releases as activate when we have seen both an
+       enter an a motion event.
+
 2004-06-01  Federico Mena Quintero  <federico@ximian.com>
 
        * gtk/gtkfilesystemmodel.c (do_files_removed): Don't insert a
index 93903f4e27aa8fb4012db3f729f48edff16b7090..bcce53faa95d6e420d35404069dc8a46d3eea205 100644 (file)
@@ -1,3 +1,14 @@
+Wed Jun  2 00:39:58 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_button_release): Make menus
+       only stay up if you release within 500 milliseconds.
+       (gtk_menu_shell_button_press): Set the activate_time to the event
+       time when a button is pressed.
+
+       * gtk/gtkmenu.c (gtk_menu_motion_notify, gtk_menu_enter_notify):
+       Interprete button releases as activate when we have seen both an
+       enter an a motion event.
+
 2004-06-01  Federico Mena Quintero  <federico@ximian.com>
 
        * gtk/gtkfilesystemmodel.c (do_files_removed): Don't insert a
index 93903f4e27aa8fb4012db3f729f48edff16b7090..bcce53faa95d6e420d35404069dc8a46d3eea205 100644 (file)
@@ -1,3 +1,14 @@
+Wed Jun  2 00:39:58 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_button_release): Make menus
+       only stay up if you release within 500 milliseconds.
+       (gtk_menu_shell_button_press): Set the activate_time to the event
+       time when a button is pressed.
+
+       * gtk/gtkmenu.c (gtk_menu_motion_notify, gtk_menu_enter_notify):
+       Interprete button releases as activate when we have seen both an
+       enter an a motion event.
+
 2004-06-01  Federico Mena Quintero  <federico@ximian.com>
 
        * gtk/gtkfilesystemmodel.c (do_files_removed): Don't insert a
index 93903f4e27aa8fb4012db3f729f48edff16b7090..bcce53faa95d6e420d35404069dc8a46d3eea205 100644 (file)
@@ -1,3 +1,14 @@
+Wed Jun  2 00:39:58 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_button_release): Make menus
+       only stay up if you release within 500 milliseconds.
+       (gtk_menu_shell_button_press): Set the activate_time to the event
+       time when a button is pressed.
+
+       * gtk/gtkmenu.c (gtk_menu_motion_notify, gtk_menu_enter_notify):
+       Interprete button releases as activate when we have seen both an
+       enter an a motion event.
+
 2004-06-01  Federico Mena Quintero  <federico@ximian.com>
 
        * gtk/gtkfilesystemmodel.c (do_files_removed): Don't insert a
index b595a312e0d3f9ce917453d504fffd7fd8e7ef0a..35bfe197a1fd324242776c5c53a62138a317ff12 100644 (file)
@@ -75,6 +75,9 @@ struct _GtkMenuAttachData
 
 struct _GtkMenuPrivate 
 {
+  gboolean seen_motion;
+  gboolean seen_enter;
+    
   gboolean have_position;
   gint x;
   gint y;
@@ -1268,6 +1271,7 @@ gtk_menu_popup (GtkMenu               *menu,
   GtkWidget *parent;
   GdkEvent *current_event;
   GtkMenuShell *menu_shell;
+  GtkMenuPrivate *priv = gtk_menu_get_private (menu);
 
   g_return_if_fail (GTK_IS_MENU (menu));
   
@@ -1275,6 +1279,9 @@ gtk_menu_popup (GtkMenu               *menu,
   menu_shell = GTK_MENU_SHELL (menu);
   
   menu_shell->parent_menu_shell = parent_menu_shell;
+
+  priv->seen_motion = FALSE;
+  priv->seen_enter = FALSE;
   
   /* Find the last viewable ancestor, and make an X grab on it
    */
@@ -2714,7 +2721,20 @@ gtk_menu_motion_notify  (GtkWidget          *widget,
   gboolean need_enter;
 
   if (GTK_IS_MENU (widget))
-    gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+    {
+      GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (widget));
+      
+      gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+      priv->seen_motion = TRUE;
+      if (priv->seen_enter)
+       {
+         /* After having seen both a motion event and an enter event,
+          * button releases should be interpreted to mean "activate"
+          */
+         
+         GTK_MENU_SHELL (widget)->activate_time = 0;
+       }
+    }
 
   /* We received the event for one of two reasons:
    *
@@ -2945,9 +2965,19 @@ gtk_menu_enter_notify (GtkWidget        *widget,
   if (widget && GTK_IS_MENU (widget))
     {
       GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
+      GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (widget));
 
       if (!menu_shell->ignore_enter)
        gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+
+      priv->seen_enter = TRUE;
+      if (priv->seen_motion)
+       {
+         /* After having seen both a motion event and an enter event,
+          * button releases should be interpreted to mean "activate"
+          */
+         menu_shell->activate_time = 0;
+       }
     }
   
   /* If this is a faked enter (see gtk_menu_motion_notify), 'widget'
index df9a9e2cc8b358dfaa6191922130304a5f7720e9..d28ca30cf2947cf56d3c1e69c56102ba4d9adaf4 100644 (file)
@@ -454,9 +454,10 @@ gtk_menu_shell_button_press (GtkWidget      *widget,
              (menu_item != menu_shell->active_menu_item))
            {
              if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
-               g_object_set_data (G_OBJECT (menu_shell),
-                                  "gtk-menushell-just-activated",
-                                  GUINT_TO_POINTER (1));
+               {
+                 menu_shell->activate_time = event->time;
+               }
+      
              gtk_menu_shell_select_item (menu_shell, menu_item);
            }
        }
@@ -488,8 +489,6 @@ gtk_menu_shell_button_release (GtkWidget      *widget,
   menu_shell = GTK_MENU_SHELL (widget);
   if (menu_shell->active)
     {
-      gboolean deactivate_immediately = FALSE;
-
       if (menu_shell->button && (event->button != menu_shell->button))
        {
          menu_shell->button = 0;
@@ -502,23 +501,8 @@ gtk_menu_shell_button_release (GtkWidget      *widget,
 
       deactivate = TRUE;
 
-      if (menu_item
-         && GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
-       {
-         if (g_object_get_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated"))
-           g_object_set_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated", NULL);
-         else
-           deactivate_immediately = TRUE;
-       }
-
       if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT)
        {
-         if (deactivate_immediately)
-           {
-             gtk_menu_shell_deactivate (menu_shell);
-             return TRUE;
-           }
-           
          if (menu_item && (menu_shell->active_menu_item == menu_item) &&
              _gtk_menu_item_is_selectable (menu_item))
            {
@@ -528,8 +512,12 @@ gtk_menu_shell_button_release (GtkWidget      *widget,
                  return TRUE;
                }
            }
-         else if (menu_item && !_gtk_menu_item_is_selectable (menu_item))
-           deactivate = FALSE;
+         else if (menu_item &&
+                  !_gtk_menu_item_is_selectable (menu_item) &&
+                  GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
+           {
+             deactivate = FALSE;
+           }
          else if (menu_shell->parent_menu_shell)
            {
              menu_shell->active = TRUE;
@@ -539,8 +527,11 @@ gtk_menu_shell_button_release (GtkWidget      *widget,
 
          /* If we ended up on an item with a submenu, leave the menu up.
           */
-         if (menu_item && (menu_shell->active_menu_item == menu_item))
-           deactivate = FALSE;
+         if (menu_item && (menu_shell->active_menu_item == menu_item) &&
+             GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
+           {
+             deactivate = FALSE;
+           }
        }
       else /* a very fast press-release */
        {
@@ -745,6 +736,7 @@ gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell)
     {
       menu_shell->button = 0;
       menu_shell->active = FALSE;
+      menu_shell->activate_time = 0;
 
       if (menu_shell->active_menu_item)
        {